package com.libre.watermark;


import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
/***
 *  图片水印
 */
public class  Watermark {
    /**
     * 添加文字水印
     *
     * @param waterMarkText 水印文字内容
     * @param fontName      字体名称， 如：宋体
     * @param fontStyle     字体样式，如：粗体和斜体(Font.BOLD|Font.ITALIC)
     * @param color         字体颜色
     * @param degree        水印文字顺时针旋转角度，允许为负数。
     * @param alpha         透明度(0.0 -- 1.0, 0.0为完全透明，1.0为完全不透明)
     * @param isOpen        是否添加水印
     */
    public static byte[] watermarkAdd(byte[] image, String waterMarkText, String fontName, int fontStyle, Color color, Integer degree,
                                      float alpha, String isOpen) {
        if (null == image)
            return null;

        if ("off".equalsIgnoreCase(isOpen))
            return image;

        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            // 得到源图片
            Image srcImg = ImageIO.read(new ByteArrayInputStream(image));
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);

            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
            // 设置水印文字大小
            int fontSize = buffImg.getWidth(null) / 300 * 8;
            // 设置水印Font
            g.setFont(new Font(fontName, fontStyle, fontSize));
            // 设置水印文字颜色
            g.setColor(color);
            // 设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) imgWidth / 2, (double) imgHeight / 2);
            }
            // 设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));

            // 计算水印文字的大小
            int textWidth = fontSize * getLength(waterMarkText);
            int textHeight = fontSize;
            // 循环打印多个水印
            for (int y = -imgHeight; y < imgHeight * 2; y += textHeight + fontSize * 3) {
                for (int x = 0; x < imgWidth * 2; x += textWidth + fontSize * 3 / 2) {
                    // 笫一参数-> 设置的内容,后面两个参数->文字在图片上的坐标位置
                    g.drawString(waterMarkText, x, y);
                }
            }
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            // 释放资源
            g.dispose();
            // 生成图片
            ImageIO.write(buffImg, "JPG", os);
            return os.toByteArray();
        } catch (IOException e) {

        }
        return image;
    }

    /**
     * 获取字符长度，一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符
     *
     * @param text
     * @return 字符长度，如：text="中文",返回 2；text="test",返回 2；text="中文ABC",返回 4.
     */
    public static int getLength(String text) {
        int textLength = text.length();
        int length = textLength;
        for (int i = 0; i < textLength; i++) {
            if (String.valueOf(text.charAt(i)).getBytes().length > 1) {
                length++;
            }
        }
        return (length % 2 == 0) ? length / 2 : length / 2 + 1;
    }

    private static String path = System.getProperty("user.dir") + "\\src\\main\\resources\\wm\\";
    public static void main(String[] args) throws Exception {
        byte[] bytes = watermarkAdd(image2byte(path+"bg1.jpg"), "版权所有", "宋体", Font.TRUETYPE_FONT, Color.RED, 10,
                0.5F, "true");
        byte2image(bytes,path+"bb.jpg");
    }


    //图片到byte数组
    public static byte[] image2byte(String path) {
        byte[] data = null;
        FileImageInputStream input = null;
        try {
            input = new FileImageInputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
            output.close();
            input.close();
        } catch (FileNotFoundException ex1) {
            ex1.printStackTrace();
        } catch (IOException ex1) {
            ex1.printStackTrace();
        }
        return data;
    }

    //byte数组到图片
    public static void byte2image(byte[] data, String path) {
        if (data.length < 3 || path.equals("")) return;
        try {
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in " + path);
        } catch (Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }

    //byte数组到16进制字符串
    public String byte2string(byte[] data) {
        if (data == null || data.length <= 1) return "0x";
        if (data.length > 200000) return "0x";
        StringBuffer sb = new StringBuffer();
        int buf[] = new int[data.length];
        //byte数组转化成十进制
        for (int k = 0; k < data.length; k++) {
            buf[k] = data[k] < 0 ? (data[k] + 256) : (data[k]);
        }
        //十进制转化成十六进制
        for (int k = 0; k < buf.length; k++) {
            if (buf[k] < 16) sb.append("0" + Integer.toHexString(buf[k]));
            else sb.append(Integer.toHexString(buf[k]));
        }
        return "0x" + sb.toString().toUpperCase();
    }
}
